package cn.wizzer.app.web.modules.controllers.platform.sys;

import cn.wizzer.app.bus.modules.models.BusinessFileInfo;
import cn.wizzer.app.bus.modules.services.*;
import cn.wizzer.app.sys.modules.models.Sys_msg;
import cn.wizzer.app.sys.modules.models.Sys_msg_user;
import cn.wizzer.app.sys.modules.models.Sys_user;
import cn.wizzer.app.sys.modules.services.SysMsgService;
import cn.wizzer.app.sys.modules.services.SysMsgUserService;
import cn.wizzer.app.sys.modules.services.SysUserService;
import cn.wizzer.app.web.commons.ext.websocket.WkNotifyService;
import cn.wizzer.app.web.commons.slog.annotation.SLog;
import cn.wizzer.app.web.commons.utils.DateUtil;
import cn.wizzer.app.web.commons.utils.StringUtil;
import cn.wizzer.framework.base.Result;
import cn.wizzer.framework.page.Pagination;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@IocBean
@At("/platform/sys/msg/user")
public class SysMsgUserController {
    private static final Log log = Logs.get();
    @Inject
    private SysMsgUserService sysMsgUserService;
    @Inject
    private SysMsgService sysMsgService;

    @Inject
    private SysUserService sysUserService;

    @Inject
    private BusinessFileInfoService businessFileInfoService;


    @Inject
    private YJbxxLzxxService yjbxxlzxxservice;
    @Inject
    private YJbxxLcxxService yjbxxlcxxservice;
    @Inject
    private RedisService redisService;
    @Inject
    BusEquipmentCheckService busEquipmentCheckService;
    @Inject
    BusEquipmentInspectionService busEquipmentInspectionService;
    @Inject
    BusEquipmentPortableService busEquipmentPortableService;
    @Inject
    BusEquipmentServicingService busEquipmentServicingService;
    @Inject
    BusEquipmentStatusService busEquipmentStatusService;
    @Inject
    BusEquipmentScrapService busEquipmentScrapService;
    @Inject
    BusEquipmentReportService busEquipmentReportService;
    @At({"/all", "/all/?"})
    @Ok("beetl:/platform/sys/msg/user/indexAll.html")
    @RequiresPermissions("sys.msg.all")
    public void index(String type, HttpServletRequest req) {
        req.setAttribute("type", Strings.isBlank(type) ? "all" : type);
    }

    @At({"/read", "/read/?"})
    @Ok("beetl:/platform/sys/msg/user/indexRead.html")
    @RequiresPermissions("sys.msg.read")
    public void read(String type, HttpServletRequest req) {
        req.setAttribute("type", Strings.isBlank(type) ? "all" : type);

    }

    @At({"/unread", "/unread/?"})
    @Ok("beetl:/platform/sys/msg/user/indexUnread.html")
    @RequiresPermissions("sys.msg.unread")
    public void unread(String type, HttpServletRequest req) {
        req.setAttribute("type", Strings.isBlank(type) ? "all" : type);
    }

    @At("/data/?")
    @Ok("json:full")
    @RequiresPermissions(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, logical = Logical.OR)
    public Object data(String status, @Param("searchType") String type, @Param("title") String title,@Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
        try {
            Cnd cnd = Cnd.NEW();
            if (Strings.isNotBlank(status) && "read".equals(status)) {
                cnd.and("a.status", "=", 1);
            }
            if (Strings.isNotBlank(status) && "unread".equals(status)) {
                cnd.and("a.status", "=", 0);
            }
            cnd.and("a.loginname", "=", StringUtil.getPlatformLoginname());
            cnd.and("a.delFlag", "=", false);
            cnd.and("b.delFlag", "=", false);
            cnd.and("b.status", "=", 1);
            cnd.desc("a.opAt");
            if (Strings.isNotBlank(type) && !"all".equals(type)) {
                cnd.and("b.type", "=", type);
            }
            if (Strings.isNotBlank(title)) {
                cnd.and("b.title", " like ", "%"+title+"%");
            }
            Sql sql = Sqls.create("SELECT b.type,b.title,b.sendat,b.msgType,a.* FROM sys_msg b LEFT JOIN sys_msg_user a ON b.id=a.msgid $condition");
            sql.setCondition(cnd);
            Sql sqlCount = Sqls.create("SELECT count(*) FROM sys_msg b LEFT JOIN sys_msg_user a ON b.id=a.msgid $condition");
            sqlCount.setCondition(cnd);
           // List list = .getList();
            Pagination p = new Pagination();
            if (Strings.isNotBlank(type) && ("all".equals(type) || "sys".equals(type))&&Strings.isNotBlank(status) && !"read".equals(status)) {
                List<NutMap> list = setMsgList();
                List<NutMap> newlist = new ArrayList<>();
                if (list.size() >= pageNumber * pageSize) {
                    newlist = list.stream().skip((pageNumber - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
                    p = sysMsgService.listPage(pageNumber, 0, sql, sqlCount);
                    p.setTotalCount(p.getTotalCount()+list.size());
                    p.setList(newlist);
                    p.setPageSize(pageSize);
                } else {
                    int listPage = Math.floorDiv(list.size(),pageSize);
                    if(list.size()>=(pageNumber-1) * pageSize) {
                        newlist = list.stream().skip((pageNumber-1) * pageSize).limit(pageSize).collect(Collectors.toList());
                    }
                    p = sysMsgService.listPage(pageNumber -listPage , pageSize, sql, sqlCount);
                    List l = p.getList();
                    newlist.addAll(l);
                    p.setTotalCount(p.getTotalCount()+list.size());
                    p.setList(newlist);
                }
            }else{
                p = sysMsgService.listPage(pageNumber, pageSize, sql, sqlCount);
            }
            return Result.success().addData(p);
        } catch (Exception e) {
            return Result.error();
        }
    }

    @At({"/delete/?", "/delete"})
    @Ok("json")
    @RequiresPermissions(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, logical = Logical.OR)
    @SLog(tag = "站内消息", msg = "${req.getAttribute('id')}")
    public Object delete(String id, @Param("ids") String[] ids, HttpServletRequest req) {
        try {
            if (ids != null && ids.length > 0) {
                sysMsgUserService.update(Chain.make("delFlag", true)
                        .add("opAt", Times.getTS()).add("opBy", StringUtil.getPlatformUid()), Cnd.where("id", "in", ids).and("loginname", "=", StringUtil.getPlatformLoginname()));
                req.setAttribute("id", org.apache.shiro.util.StringUtils.toString(ids));
            } else {
                sysMsgUserService.update(Chain.make("delFlag", true)
                        .add("opAt", Times.getTS()).add("opBy", StringUtil.getPlatformUid()), Cnd.where("id", "=", id).and("loginname", "=", StringUtil.getPlatformLoginname()));
                req.setAttribute("id", id);
            }
            sysMsgUserService.deleteCache(StringUtil.getPlatformLoginname());
            return Result.success();
        } catch (Exception e) {
            return Result.error();
        }
    }

    @At
    @Ok("json")
    public Object unread_num() {
        try {
            NutMap nutMap = NutMap.NEW();
            nutMap.put("system", sysMsgUserService.count(Sqls.create("SELECT count(*) from sys_msg a,sys_msg_user b WHERE a.id=b.msgId AND a.type='system' AND a.delFlag=false AND b.status=0 AND b.delFlag=false AND b.loginname=@loginname").setParam("loginname", StringUtil.getPlatformLoginname())));
            nutMap.put("user", sysMsgUserService.count(Sqls.create("SELECT count(*) from sys_msg a,sys_msg_user b WHERE a.id=b.msgId AND a.type='user' AND a.delFlag=false AND b.status=0 AND b.delFlag=false AND b.loginname=@loginname").setParam("loginname", StringUtil.getPlatformLoginname())));
            return Result.success().addData(nutMap);
        } catch (Exception e) {
            return Result.error();
        }
    }

    @At("/status/read")
    @Ok("json")
    @RequiresPermissions(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, logical = Logical.OR)
    @SLog(tag = "站内消息", msg = "${req.getAttribute('id')}")
    public Object read(@Param("ids") String[] ids, HttpServletRequest req) {
        try {
            sysMsgUserService.update(Chain.make("status", 1).add("readAt", Times.getTS())
                    .add("opAt", Times.getTS()).add("opBy", StringUtil.getPlatformUid()), Cnd.where("id", "in", ids).and("loginname", "=", StringUtil.getPlatformLoginname()));
            sysMsgUserService.deleteCache(StringUtil.getPlatformLoginname());
            req.setAttribute("id", org.apache.shiro.util.StringUtils.toString(ids));
            return Result.success("system.success");
        } catch (Exception e) {
            return Result.error("system.error");
        }
    }

    @At("/status/readAll")
    @Ok("json")
    @RequiresPermissions(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, logical = Logical.OR)
    @SLog(tag = "站内消息", msg = "readAll")
    public Object readAll(HttpServletRequest req) {
        try {
            sysMsgUserService.update(Chain.make("status", 1).add("readAt", Times.getTS())
                    .add("opAt", Times.getTS()).add("opBy", StringUtil.getPlatformUid()), Cnd.where("loginname", "=", StringUtil.getPlatformLoginname()));
            sysMsgUserService.deleteCache(StringUtil.getPlatformLoginname());
            return Result.success();
        } catch (Exception e) {
            return Result.error();
        }
    }

    @At("/all/detail/?")
    @Ok("beetl:/platform/sys/msg/user/detailAll.html")
    @RequiresPermissions(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, logical = Logical.OR)
    public void allDetail(String id, HttpServletRequest req) {
        if (!Strings.isBlank(id)) {
            //判断用户是否是正常获取消息
            Sys_msg_user msgUser = sysMsgUserService.fetch(Cnd.where("msgid", "=", id).and("loginname", "=", StringUtil.getPlatformLoginname()));
            if (msgUser != null) {
                msgUser.setStatus(1);
                sysMsgUserService.update(msgUser);
                sysMsgUserService.clearCache();
                Sys_msg msg = sysMsgService.fetch(id);
                req.setAttribute("obj", msg);
                req.setAttribute("user", sysUserService.fetch(msg.getOpBy()));
                List<BusinessFileInfo> files = new ArrayList<>();
                if(StringUtils.isNotBlank(msg.getFileId())){
                    //获取文件信息
                    String ids = "('"+msg.getFileId().replace(",","','")+"')";
                    files =  businessFileInfoService.listEntity(Sqls.create("select * from bus_file_info where id in "+ids));
                }
                req.setAttribute("files", files);
            } else {
                req.setAttribute("obj", null);
            }
        } else {
            req.setAttribute("obj", null);
        }
    }

    @At("/read/detail/?")
    @Ok("beetl:/platform/sys/msg/user/detailRead.html")
    @RequiresPermissions(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, logical = Logical.OR)
    public void readDetail(String id, HttpServletRequest req) {
        if (!Strings.isBlank(id)) {
            //判断用户是否是正常获取消息
            Sys_msg_user msgUser = sysMsgUserService.fetch(Cnd.where("msgid", "=", id).and("loginname", "=", StringUtil.getPlatformLoginname()));
            if (msgUser != null) {
                msgUser.setStatus(1);
                sysMsgUserService.update(msgUser);
                sysMsgUserService.clearCache();
               // req.setAttribute("obj", sysMsgService.fetch(id));
                Sys_msg msg = sysMsgService.fetch(id);
                req.setAttribute("obj", msg);
                req.setAttribute("user", sysUserService.fetch(msg.getOpBy()));
                List<BusinessFileInfo> files = new ArrayList<>();
                if(StringUtils.isNotBlank(msg.getFileId())){
                    //获取文件信息
                    String ids = "('"+msg.getFileId().replace(",","','")+"')";
                    files =  businessFileInfoService.listEntity(Sqls.create("select * from bus_file_info where id in "+ids));
                }
                req.setAttribute("files", files);
            } else {
                req.setAttribute("obj", null);
            }
        } else {
            req.setAttribute("obj", null);
        }
    }

    @At("/unread/detail/?")
    @Ok("beetl:/platform/sys/msg/user/detailUnread.html")
    @RequiresPermissions(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, logical = Logical.OR)
    public void unreadDetail(String id, HttpServletRequest req) {
        if (!Strings.isBlank(id)) {
            //判断用户是否是正常获取消息
            Sys_msg_user msgUser = sysMsgUserService.fetch(Cnd.where("msgid", "=", id).and("loginname", "=", StringUtil.getPlatformLoginname()));
            if (msgUser != null) {
                msgUser.setStatus(1);
                sysMsgUserService.update(msgUser);
                sysMsgUserService.clearCache();
                //req.setAttribute("obj", sysMsgService.fetch(id));
                Sys_msg msg = sysMsgService.fetch(id);
                req.setAttribute("obj", msg);
                req.setAttribute("user", sysUserService.fetch(msg.getOpBy()));
                List<BusinessFileInfo> files = new ArrayList<>();
                if(StringUtils.isNotBlank(msg.getFileId())){
                    //获取文件信息
                    String ids = "('"+msg.getFileId().replace(",","','")+"')";
                    files =  businessFileInfoService.listEntity(Sqls.create("select * from bus_file_info where id in "+ids));
                }
                req.setAttribute("files", files);
            } else {
                req.setAttribute("obj", null);
            }
        } else {
            req.setAttribute("obj", null);
        }
    }



    private List<NutMap> setMsgList() {
//b.type,b.title,b.sendat,b.msgType,id,msgId,loginname,status,readAt
        List<NutMap> mapList = new ArrayList<>();
        Sys_user user = StringUtil.getPlatformUser();
        String loginname = user.getLoginname();
        int transferredCount = yjbxxlzxxservice.getTransferredCount(loginname);//待移交数量
        if(transferredCount>0){
            String url = "/platform/bus/ypxx/transfer";
            String title = "【样品移交】待移交样品,<span style='color:red'>"+transferredCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }
        int toReceivedCount = yjbxxlzxxservice.getToReceivedCount(loginname);
        if(toReceivedCount>0){
            String url = "/platform/bus/ypxx/transfer";
            String title = "【样品移交】待接收样品,<span style='color:red'>"+toReceivedCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }
        int adReceivedCount = yjbxxlzxxservice.getAdReceivedCount(loginname);
        if(adReceivedCount>0){
            String url = "/platform/bus/ypxx/transfer";
            String title = "【样品移交】已接收，待处置样品,<span style='color:red'>"+adReceivedCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }
        int  taskCount = yjbxxlcxxservice.getTaskCount(loginname);
        if(taskCount>0){
            String url = "/platform/bus/rwgl/rwfp";
            String title = "【任务分配】待分配任务,<span style='color:red'>"+taskCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }
        int  workCount = yjbxxlcxxservice.getWorkCount(loginname);
        if(workCount>0){
            String url = "/platform/bus/bggl/bz";
            String title = "【报告编制】待编制报告,<span style='color:red'>"+workCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }
        int  examineCount = yjbxxlcxxservice.getExamineCount(loginname);
        if(examineCount>0){
            String url = "/platform/bus/bggl/sh";
            String title = "【报告审核】待审核报告,<span style='color:red'>"+examineCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }
        int  approveCount = yjbxxlcxxservice.getApproveCount(loginname);
        if(approveCount>0){
            String url = "/platform/bus/bggl/pz";
            String title = "【报告批准】待批准报告,<span style='color:red'>"+approveCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }
        int  printCount = yjbxxlcxxservice.getPrintCount(loginname);
        if(printCount>0){
            String url = "/platform/bus/bggl/dy";
            String title = "【报告打印】待打印报告,<span style='color:red'>"+printCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }
        //设备消息

        int servicingDepartmentCount=busEquipmentServicingService.getAuditCount(user);
        if(servicingDepartmentCount>0){
            String url = "/platform/bus/equipment/servicing/audit";
            String title = "【设备维修】待审核,<span style='color:red'>"+servicingDepartmentCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }

        int servicingCompleteCount=busEquipmentServicingService.getCompleteCount(user);
        if(servicingCompleteCount>0){
            String url = "/platform/bus/equipment/servicing/complete";
            String title = "【设备维修】待维修完成,<span style='color:red'>"+servicingCompleteCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }
        //
        int statusDepartmentCount=busEquipmentStatusService.getAuditCount(user);
        if(statusDepartmentCount>0){
            String url = "/platform/bus/equipment/status/audit";
            String title = "【设备启用/停用】待审核,<span style='color:red'>"+statusDepartmentCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }


//
        int scrapDepartmentCount=busEquipmentScrapService.getAuditCount(user);
        if(scrapDepartmentCount>0){
            String url = "/platform/bus/equipment/scrap/audit";
            String title = "【设备报废】待审核,<span style='color:red'>"+scrapDepartmentCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }

        int reportDepartmentCount=busEquipmentReportService.getAuditCount(user);
        if(reportDepartmentCount>0){
            String url = "/platform/bus/equipment/report/audit";
            String title = "【设备确认】待审核,<span style='color:red'>"+reportDepartmentCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }


        int portableDepartmentCount=busEquipmentPortableService.getAuditCount(user);//外携
        if(portableDepartmentCount>0){
            String url = "/platform/bus/equipment/portable/audit";
            String title = "【设备借出】待审核,<span style='color:red'>"+portableDepartmentCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }
        int portableCompleteCount=busEquipmentPortableService.getCompleteCount(user);//外携
        if(portableCompleteCount>0){
            String url = "/platform/bus/equipment/portable/complete";
            String title = "【设备借出】待设备返回,<span style='color:red'>"+portableCompleteCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }
        int checkDepartmentCount=busEquipmentCheckService.getCheckAuditCount(user);
        if(checkDepartmentCount>0){
            String url = "/platform/bus/equipment/check/audit";
            String title = "【设备维护】待审核,<span style='color:red'>"+checkDepartmentCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }

        int inspectionCompleteCount=busEquipmentInspectionService.getCompleteCount(user);//送检
        if(inspectionCompleteCount>0){
            String url = "/platform/bus/equipment/inspection/complete";
            String title = "【设备送检】待送回,<span style='color:red'>"+inspectionCompleteCount+"</span>条，请及时处置！";
            mapList.add(NutMap.NEW().addv("type", "系统消息")
                    .addv("msgtype", WkNotifyService.typeMap.get("bus"))
                    .addv("title", title)
                    .addv("url", url)
                    .addv("time", DateUtil.getDate()));
        }
        return mapList;
    }
}
